// ============================================================================
//
// Graph framework by Aurelien Moreau aurelien.moreau@gmail.com
// Modified by Pierre CHATEL chatelp@gmail.com
// Distributed under LGPL
// Copyright (C) Aurelien Moreau, 2008, 2009. All rights reserved
//
// ============================================================================

package com.thalesgroup.graphFramework.core.impl;

import java.util.ArrayList;
import java.util.Iterator;

import com.thalesgroup.graphFramework.core.Edge;
import com.thalesgroup.graphFramework.core.Graph;
import com.thalesgroup.graphFramework.core.Vertex;
import com.thalesgroup.graphFramework.core.utils.DOTTools;

import com.thalesgroup.graphFramework.collections.DETabular;
import com.thalesgroup.graphFramework.collections.iterator.ArrayIterator;

public class GraphImpl<V, E> implements Graph<V, E> {

	/**
	 * Ajout pierre du 13/08/08
	 */
	protected DOTTools<V, E> serializer = new DOTTools<V, E>();
	
	protected VertexImpl<V,E>[] vertices;
	
	protected EdgeImpl<V,E>[] edges;

	protected DETabular<Vertex<V, E>, Edge<V, E>> m;

	protected GraphImpl() {
		m = new DETabular<Vertex<V, E>, Edge<V, E>>();
	}

	protected GraphImpl(final GraphImpl<V, E> source) {
		m = new DETabular<Vertex<V, E>, Edge<V, E>>(source.m);
	}

	public void finalizeGraph(VertexImpl<V,E>[] vertices, EdgeImpl<V,E>[] edges) {
		this.vertices=vertices;
		this.edges=edges;
		
		for (int i = 0; i < edges.length; i++) {
			final EdgeImpl<V, E> e = edges[i];
			final Vertex<V, E> src = e.getIn();
			final Vertex<V, E> tgt = e.getOut();
			m.set(src, tgt, e);
		}
	}

	public Edge<V, E> getEdge(final Vertex<V, E> src, final Vertex<V, E> tgt) {
		return m.get(src, tgt);
	}

	public Edge<V, E> getEdge(int index) {
		return edges[index];
	}

	public Iterator<Edge<V, E>> getEdges() {
		return new ArrayIterator<Edge<V,E>>(edges);
	}

	public int getEdgesSize() {
		return edges.length;
	}

	public Vertex<V, E> getVertex(int index) {
		return vertices[index];
	}

	public Iterator<Vertex<V, E>> getVertices() {
		return new ArrayIterator<Vertex<V,E>>(vertices);
	}

	public int getVerticesSize() {
		return vertices.length;
	}
	
	/**
	 * Ajout pierre du 13/08/08
	 */
	public void setSerializer(DOTTools<V, E> serializer) {
		this.serializer = serializer;
	}
	
	/**
	 * Ajout pierre du 13/08/08
	 */
	public String toString() {
		StringBuffer buffer=new StringBuffer();
		serializer.graph2dot(this, buffer);

		return buffer.toString();
	}
	
	/**
	 * Ajout pierre du 14/08/08
	 * @param vertex
	 * @return
	 */
	public Vertex<V, E>[] getAdjacentVertices(Vertex<V, E> source) {
		ArrayList<Vertex<V, E>> adjacentVertices = new ArrayList<Vertex<V, E>>();
		
		for(Iterator<Vertex<V, E>> vi = this.getVertices(); vi.hasNext();) {
			Vertex<V, E> target = vi.next();
			Edge<V, E> edge = m.get(source, target);
			if(edge != null)
				adjacentVertices.add(target);
		}
		
		Vertex<V, E>[] array = new Vertex[adjacentVertices.size()];
		
		return  adjacentVertices.toArray(array);
	}

}
